<?php
/**
 * Extended class of factory class Zend_Http_Client provides the method of abstracting api calls to the Ebay AP
 * @category Ebay
 * @package Ebay_Codes
 * @author Luke Parry
 */
require_once 'Zend/Config/Ini.php';

class Ebay_HttpClient extends Zend_Http_Client
{
	protected $_baseUriList = array('Sandbox' 	 => 'https://api.sandbox.ebay.com/ws/api.dll',
									'Production' => 'https://api.ebay.com/ws/api.dll');
	protected $_ready = false;
    protected $_config;
	
    static $authToken;
	static $debug = false;
	
	
	/**
	 * Sets the Auth token for all Ebay_HttpClient classes constructed
	 * @param string $token the Ebay API request token
	 * @static
	 */
    static function setAuthToken($token)
    {
        self::$authToken = $token;
    }
	
	
	/**
	 * Initialise the class once calling the base class constructor
	 * @param string $server
	 */
	public function __construct($server = null)
	{
		// Call the parent  constructor for Zend_Http_Client
		parent::__construct();
		$this->init($server);
	}
	
	/**
	 * Debugs and throws the request made
	 * @param boolean $mode toggles whethe this option is enabled
	 * @static
	 */
	static function debugOutput($mode = true)
	{
		self::$debug = $mode;
	}
	
	
    /**
	 * Initialise the class once it has been constructed
	 * @param string $server
	 */
	public function init($server = null)
	{
		if($this->_ready)
		{
			return true;
		}
		
        //Enable SSL connections to the server
        $this->setConfig( array('adapter'      => 'Zend_Http_Client_Adapter_Socket',
                                'ssltransport' => 'tls' ));

		// Get an instance of the Zend Registry
        $registry = Zend_Registry::getInstance();
		
		// Load the configuration set in Zend_Registry					
        $this->_config = $registry->get('config')->ebay->api;

        $server = (isset($server)) ? $server : $this->_config->server;
		
		if(!isset($this->_baseUriList[ $server ]))
		{
			throw new Ebay_Exception("Server Mode is not valid");
		}

		$this->setUri($this->_baseUriList[$server]);
		$this->setHeaders(array('X-EBAY-API-COMPATIBILITY-LEVEL'  => $this->_config->version,
								'X-EBAY-API-SITEID'				  => $this->_config->siteid,
                                'X-EBAY-API-APP-NAME' 			  => $this->_config->appName,
                                'X-EBAY-API-DEV-NAME' 			  => $this->_config->devName,
                                'X-EBAY-API-CERT-NAME' 			  => $this->_config->certName,
								'Content-Type' 					  => 'text/xml'));
		$this->_ready = true;
		//$this->setEncType('text/xml'); //Might be needed
	}

    /**
	 * Makes the Actual api call to the Ebay servers using the configuration initialised in the constructor for this class
	 * @param string $request
	 * @param Ebay_XmlWriter $params
	 * @throws Ebay_Exception
	 * @returns SimpleXMLElement
	 */
	public function call($request, $params)
	{
        $params = (string) $params;
        $xml = new Ebay_XmlWriter();
        $xml->create(true)->push($request.'Request', null, array('xmlns' => 'urn:ebay:apis:eBLBaseComponents'));

        if(self::$authToken) //Add the auth token
        {
            $xml->push('RequesterCredentials')
                ->push('eBayAuthToken', self::$authToken)->pop()->pop();
        }

        $xml->push('errorLanguage', $this->_config->locale)->pop()
            ->writeRaw($params);
        $xml->end();

		if(self::$debug)
		{
			Zend_Debug::dump((string) $params);
			throw new Exception(Zend_Debug::dump((string) $params));
		}

		$this->setRawData((string) $xml)->setHeaders(array('X-EBAY-API-CALL-NAME'	=> $request,
														'Content-length'			=> strlen($xml) )); //Calculate the content length, recommended option
		$response = $this->request('POST');
		if($response->isError() || $response->getHeader('Content-Type') != 'text/xml')
		{
			throw new Ebay_Exception("An error during transmission occured ", $response->extractCode);
		}

		$response = simplexml_load_string($response->getBody());
		if($response->Ack != 'Success') //There's an error
		{
            throw new Ebay_Exception($response->Errors->LongMessage, $response->Errors->ErrorCode);
        }
        return $response;
    }
}